/*
 * ConnectionMgr.java
 *
 * Created on April 24, 2007, 3:16 PM
 *
 *  Life Logger v1.0
    Copyright (C) 2007  Anand Kishore (anand@semanticvoid.com)
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

package com.semanticvoid.lifelogger.db;

import com.semanticvoid.lifelogger.configuration.ConfigManager;
import com.semanticvoid.lifelogger.configuration.Constants;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * This class handles all the low level db functions.
 * @author anand kishore
 */
public class ConnectionMgr {
    
    /** Connection */
    Connection con;
    
    /**
     * Creates a new instance of ConnectionMgr
     * @throws java.lang.Exception throws Exception if connection to db fails
     */
    public ConnectionMgr() throws Exception {
        init();
    }
    
    /**
     * Initialize the db connection
     * @throws java.lang.Exception throws Exception if connection to db fails
     */
    private void init() throws Exception {
        ConfigManager config = ConfigManager.getInstance();
        
        String username = config.getValueForKey(Constants.KEY_FOR_DB_USERNAME);
        if (config.getValueForKey(Constants.KEY_FOR_DB_USERNAME) == null) {
            System.out.println("Username for Db is not defined.");
            username = "";
        }
        
        String passwd = config.getValueForKey(Constants.KEY_FOR_DB_PASSWD);
        if (config.getValueForKey(Constants.KEY_FOR_DB_USERNAME) == null) {
            System.out.println("Passwd for Db is not defined.");
            passwd = "";
        }
        
        String driverName = config.getValueForKey(Constants.KEY_FOR_DB_DRIVER);
        String databaseName = config.getValueForKey(Constants.KEY_FOR_DB_DATABASE_NAME);
        String urlToDb = config.getValueForKey(Constants.KEY_FOR_DB_URL);
        // if the users passes bogus information, let him repent for it!
        if ((driverName == null) || (urlToDb == null) || (databaseName == null)) {
            throw new Exception("Either of dbname, driver name or db URL were null");
        }
        
        try {
            Class driver = Class.forName(driverName);
            
            if (driver == null) {
                throw new Exception("The JDBC Driver '" + driverName + "' could not be loaded");
            }
        } catch (ClassNotFoundException classEx) {
            throw new Exception("The JDBC Driver Class : " + driverName + " is not in the classpath", classEx);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new Exception("An error occured while trying to load the driver : " + driverName, ex);
        }
        
        try {
            // driver has been loaded - we need to connect to the database using this
            con = DriverManager.getConnection(urlToDb + databaseName, username, passwd);
            
            if (con == null) {
                throw new Exception("We could not get a connection " +
                        "to the databse from the DriverManager");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new Exception("There was some unexpected exception while connecting to the database", ex);
        }
    }
    
    /**
     * Fire update queries
     * @param query the update query to be fired
     * @return true if the query fired successfully
     * false otherwise
     */
    public boolean fireUpdate(String query) {
        try {
            Statement stmt = con.createStatement();
            if(stmt.executeUpdate(query) > 0) {
                return true;
            }
        } catch(SQLException sqe) {
            int errCode = sqe.getErrorCode();
            
            //System.out.println("QUERY: " + query);
            
            // this list error codes for duplicate entriesd in not exhaustive.
            // there are many such codes. Using only those required.
            if(errCode == 1022 || errCode == 1062 || errCode == 1582)  {
                return true;
            }
            
            sqe.printStackTrace();
        } catch(Exception e) {
            e.printStackTrace();
        }
        
        return false;
    }
    
    
    /**
     * Fire select queries
     * @param query the select query to be fired
     * @return the resultset
     * null otherqise
     */
    public ResultSet fire(String query) {
        if(query != null) {
            try {
                Statement stmt = con.createStatement();
                ResultSet rs = stmt.executeQuery(query);
                
                return rs;
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
        
        return null;
    }
}
